package net.sunzc.hwfacetest.utils;

import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class FileUtils {
    private static final String TAG = "FileUtils";

    /**
     * @param filename
     * @return
     * @throws IOException
     */
    public static List<ByteArrayOutputStream> toByteArray(String filename)
            throws IOException {
        List<ByteArrayOutputStream> list = new ArrayList<ByteArrayOutputStream>();
        File f = new File(filename);
        if (!f.exists()) {
            throw new FileNotFoundException(filename);
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream(530);
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 730;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
                list.add(bos);
                bos = new ByteArrayOutputStream(730);
            }

        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
        return list;
    }

    public static ByteArrayOutputStream toByteData(String filename)
            throws IOException {
        File f = new File(filename);
        if (!f.exists()) {
            throw new FileNotFoundException(filename);
        }
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(f));
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            is.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
        return bos;
    }

    public static final int SIZETYPE_B = 1;// 获取文件大小单位为B的double值
    public static final int SIZETYPE_KB = 2;// 获取文件大小单位为KB的double值
    public static final int SIZETYPE_MB = 3;// 获取文件大小单位为MB的double值
    public static final int SIZETYPE_GB = 4;// 获取文件大小单位为GB的double值

    public static byte[] fileToByteArray(File file) {
        int bufferSize = 1024;
        byte[] buf = new byte[bufferSize];
        ByteArrayOutputStream output;
        try {
            FileInputStream input = new FileInputStream(file);
            output = new ByteArrayOutputStream();
            int bytesRead = input.read(buf);
            while (bytesRead != -1) {
                output.write(buf, 0, bytesRead);
                bytesRead = input.read(buf);
            }
            output.flush();
            output.close();
            return output.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取文件指定文件的指定单位的大小
     *
     * @param filePath 文件路径
     * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
     * @return double值的大小
     */
    public static double getFileOrFilesSize(String filePath, int sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("获取文件大小", "获取失败!");
        }
        return FormetFileSize(blockSize, sizeType);
    }

    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath 文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    public static String getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("获取文件大小", "获取失败!");
        }
        return FormetFileSize(blockSize);
    }

    /**
     * 获取指定文件大小
     *
     * @param file
     * @return
     * @throws Exception
     */
    private static long getFileSize(File file) throws Exception {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = null;
            fis = new FileInputStream(file);
            size = fis.available();
        } else {
            file.createNewFile();
            Log.e("获取文件大小", "文件不存在!");
        }
        return size;
    }

    /**
     * 获取指定文件夹
     *
     * @param f
     * @return
     * @throws Exception
     */
    private static long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    private static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    private static double FormetFileSize(long fileS, int sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case SIZETYPE_B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case SIZETYPE_KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case SIZETYPE_MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case SIZETYPE_GB:
                fileSizeLong = Double.valueOf(df
                        .format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }

    public static String getFilePath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED); // determine whether sd
        // card is exist
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();
        } else {
            sdDir = Environment.getRootDirectory();
        }
        return sdDir.toString();
    }

    public static boolean isFileExists(String path) {
        File file = new File(path);
        try {
            if (file.isFile() && file.exists()) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    public static String getCurrentProcessName(Context context) {
        int pid = android.os.Process.myPid();//获取进程pid
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);//获取系统的ActivityManager服务
        for (ActivityManager.RunningAppProcessInfo appProcess : am.getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return "";
    }

    public static void delFile(File dir) {
        if (dir == null || !dir.exists()) return;
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                delFile(file);
            }
            dir.delete();
        } else {
            dir.delete();
        }
    }

    public static File saveBitmapToFile(Bitmap bitmap, String path) {
        File file = new File(path);
        try {
            FileOutputStream fileOutStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 10, fileOutStream);
            fileOutStream.flush();
            fileOutStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return file;
    }

    public static boolean mkDirs(String dirPath) {
        File dir = new File(dirPath);
        return dir.exists() || dir.mkdirs();
    }

    public static String readTxtFile(String path) {
        try {
            FileInputStream fos = new FileInputStream(path);
            int length = fos.available();
            byte[] textBytes = new byte[length];
            fos.read(textBytes);
            return new String(textBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将文件读取为16进制String
     * Read original File and transfer it into Hex String
     *
     * @return
     * @throws IOException
     */
    public static String readOriginal2Hex(File file) {
        StringBuilder sb = new StringBuilder();
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            int temp;
           /*16进制转化模块*/
            while ((temp = fileInputStream.read()) != -1) {
                String hexStr = String.format(Locale.CHINA, "%2s", Integer.toHexString(temp)).replace(' ', '0');
                sb.append(hexStr.substring(hexStr.length() - 2, hexStr.length()));
            }
            fileInputStream.close();
            writeText(sb.toString(), "feature1.txt");
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return sb.toString();
    }


    private static void writeText(String sb, String fileName) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter(new File("/sdcard/", fileName)));
        writer.write(sb);
        writer.close();
    }

    public static void writeFile(File featureFile, byte[] data, int length) {
        try {
            FileOutputStream out = new FileOutputStream(featureFile);
            out.write(data, 0, length);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean copyFile(String from, String to) {

        File fromFile, toFile;

        fromFile = new File(from);
        toFile = new File(to);

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            toFile.createNewFile();
            fis = new FileInputStream(fromFile);
            fos = new FileOutputStream(toFile);

            int bytesRead;
            byte[] buf = new byte[256 * 1024];// 256K buffer

            while ((bytesRead = fis.read(buf)) != -1) {
                fos.write(buf, 0, bytesRead);
            }

        } catch (IOException e) {
            MyLog.e(TAG, e.getLocalizedMessage());
            return false;
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.flush();
                    fos.close();
                }
            } catch (IOException e) {
                MyLog.i(TAG, "copy file stream close failed");
            }
        }

        return true;

    }

    public static byte[] file2Byte(File file) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            int length = fis.available();
            byte[] fileBytes = new byte[length];
            fis.read(fileBytes);
            return fileBytes;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 将替换后的16进制字符串写回文件
     * write replaced original String to file
     *
     * @param replaced
     * @throws NumberFormatException
     * @throws IOException
     */
    public static void writeNew2Binary(String replaced, File featureFile) {
        try {
            FileOutputStream fout = new FileOutputStream(featureFile);
            for (int i = 0; i < replaced.length(); i += 2) {
                fout.write(Integer.parseInt(replaced.substring(i, i + 2), 16));
            }
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static byte[] list2Array(List<byte[]> featureList) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            for (byte[] bytes : featureList) {
                baos.write(bytes);
            }
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }

    public static void writeFile(String filename, byte[] bytes) {
        File file = new File(filename);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            fos.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    public static void writeFile(String fileName, String message) {
        try {

            File file = new File(fileName);

            File fileParent = file.getParentFile();
            if (!fileParent.exists()) {
                fileParent.mkdirs();
            }

            try {
                if (!file.exists()) {
                    file.createNewFile();
                }
            } catch (IOException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }


            FileOutputStream fout = new FileOutputStream(fileName);
            byte[] bytes = message.getBytes();
            fout.write(bytes);
            fout.flush();
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void showPhoto(Context context, Bitmap photo) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        ImageView view = new ImageView(context);
        view.setImageBitmap(photo);
        final AlertDialog dialog = builder.setView(view).show();
        view.postDelayed(new Runnable() {
            @Override
            public void run() {
                dialog.dismiss();
            }
        }, 10000);
    }

    public static Bitmap getBitmap(byte[] yuvImageData, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        int width = parameters.getPreviewSize().width;
        int height = parameters.getPreviewSize().height;
        YuvImage yuv = new YuvImage(yuvImageData, parameters.getPreviewFormat(), width, height, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuv.compressToJpeg(new Rect(0, 0, width, height), 50, out);
        byte[] bytes = out.toByteArray();
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    public static String getStringFromBytes(byte[] strName) {
        byte[] tempString;
        for (int i = 0; i < strName.length; i++) {
            if (strName[i] == 0) {
                tempString = new byte[i];
                System.arraycopy(strName, 0, tempString, 0, i);
                try {
                    return new String(tempString, "utf8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
            }
        }
        return "";
    }
}
